package com.asb.service;

import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.asb.model.AuditOrder;
import com.asb.model.Copytor;
import com.asb.model.Executor;
import com.asb.model.Operator;
import com.asb.model.Order;
import com.asb.models.Jbpm4OasProcessHistory;
import com.asb.models.Movetasktable;
import com.asb.utils.LocationEnum;
import com.asb.utils.ProcessType;
import com.asb.utils.SpecialtyEnum;
import com.asb.utils.StatusEnum;
import com.jfinal.aop.Inject;
import com.jfinal.log.Log4jLog;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;

import cn.hutool.core.util.StrUtil;

/**
 * @author 订单
 * @create 2022/3/21 15:17
 */
public class OrderService {

	Movetasktable movetasktable = new Movetasktable().dao();
	private Jbpm4OasProcessHistory jbpm4OasProcessHistory = new Jbpm4OasProcessHistory().dao();

	public static final String isLeaderyes = "是";
	public static final String isLeaderno = "否";
	// 用于格式化序号
	static DecimalFormat df = new DecimalFormat("000");
	private final Log4jLog log = Log4jLog.getLog(OrderService.class);
	@Inject
	NotifyDingTalkService notifyDingTalkService;

	// 新建工单： 1、填的信息 和选的审核人信息 存在主表---movetasktable
	// 2、选的执行人抄送人存在暂存表---movetasktableper
	// 3、记录表---JBPM4_OAS_PROCESS_HISTORY
	// 4、我的任务表---tasknew
	// 5、子表--movetasktableprocess--无审核人时，直接写子表
	public Map<String, Object> create(Order order) {
		Map<String, Object> result = new HashMap<>();
		try {
			// 通过账号查询出用户信息
			Record userinfo = getUsersListByUserName(order.getProposeruser());

			// 调用通知接口数据
			Map<String, Object> notifyBody = new HashMap<>();

			// 主表ID
			Long mainId = getSqu();
			System.out.println("id:" + mainId);
			// 创建主表NO
			String no = getNo(order.getNetType(), userinfo.getStr("LOCATIONID"));
			// 创建时间和申请时间
			Date currentDate = new Date();
			// 主表信息--1、填的信息 和选的审核人信息 存在主表-
			Record movetasktable = getMovetasktable(order, userinfo, mainId, currentDate, no);
			// 2、选的执行人抄送人存在暂存表---movetasktableper
			// 直接写到了事务里
			// 3、记录表---JBPM4_OAS_PROCESS_HISTORY
			// n.getCopyToName()+"提交任务到"+n.getProposerName()+";抄送人意见："+n.getCopyToOpinion()
			// 与文档不一致todo
			String COMMENT_ = "";
			if (isLeaderyes.equals(order.getIsneedleaderuser())) {
				COMMENT_ = userinfo.getStr("NAME") + "新建工单到" + order.getLeadername();
			} else {
				COMMENT_ = userinfo.getStr("NAME") + "新建工单";
			}
			// 传输//公客 //动环 //建设//政企 //数据 //无线 //核心网//监控//线路//综合维护
			Record jbpm4_oas_process_history = getJbpm4OasProcessHistory(order, userinfo, COMMENT_, mainId);

			// 4、我的任务表---tasknew--
			// 4.1-领导审核写领导
			// 4.2-无领导审核写执行人
			/// moveTaskTable/leaderPage 领导审核页面URL
			/// moveTaskTable/executerPage 执行人执行页面URL
			/// moveTaskTable/copyToPage 抄送人执行页面URL
			/// moveTaskTable/closePage 工单关闭页面URL
			/// moveTaskTable/againMoveTaskTable 再次发起工单页面URL
			// 直接写到了事务方法中

			// 5、子表--movetasktableprocess
			List<Record> movetasktableprocessRecords = new ArrayList<>();
			// 4.2-无领导审核写执行人任务表记录
			List<Record> tasknewRecords = new ArrayList<>();
			List<Map<String, String>> users = new ArrayList<>();
			if (isLeaderno.equals(order.getIsneedleaderuser()) || "false".equals(order.getIsneedleaderuser())) {
				notifyBody.put("process_type", ProcessType.SUB_WAITING_COOPERATE);

				if (order.getExecutor() != null) {
					for (Executor executor : order.getExecutor()) {
						Record movetasktableprocess = getMovetasktableprocessForExecutor(order, userinfo, mainId,
								currentDate, no, executor);
						movetasktableprocessRecords.add(movetasktableprocess);
						// 添加执行人，执行人需要子表ID，所以写在这
						tasknewRecords.add(getExecutorTaskRecord(order, executor, movetasktableprocess.get("ID"), no,
								currentDate));
						// 用于通知

						Record execuserinfo = getUsersListByUserName(executor.getProcessinguser());
						Map<String, String> notifyuser = new HashMap<>();
						notifyuser.put("phone_number", execuserinfo.getStr("mobile"));
						notifyuser.put("activity_type", ProcessType.MAIN_WAITING_EXECUTE);
						users.add(notifyuser);
					}
				}
				if (order.getCopytor() != null) {
					for (Copytor copytor : order.getCopytor()) {
						Record movetasktableprocess = getMovetasktableprocessForCopytor(order, userinfo, mainId,
								currentDate, no, copytor);
						movetasktableprocessRecords.add(movetasktableprocess);
						// 添加执行人，执行人需要子表ID，所以写在这
						tasknewRecords.add(
								getCopytorTaskRecord(order, copytor, movetasktableprocess.get("ID"), no, currentDate));

						// 用于通知
						Record execuserinfo = getUsersListByUserName(copytor.getProcessinguser());
						Map<String, String> notifyuser = new HashMap<>();
						notifyuser.put("phone_number", execuserinfo.getStr("mobile"));
						notifyuser.put("activity_type", ProcessType.MAIN_WAITING_EXECUTE);
						users.add(notifyuser);
					}
				}
				notifyBody.put("users", users);
			} else {
				notifyBody.put("process_type", ProcessType.MAIN_AUDIT);
				Record audituserinfo = getUsersListByUserName(order.getLeaderuser());
				// 用于通知
				Map<String, String> notifyuser = new HashMap<>();
				notifyuser.put("phone_number", audituserinfo.getStr("mobile"));
				notifyuser.put("activity_type", ProcessType.MAIN_AUDIT);
				users.add(notifyuser);
				notifyBody.put("users", users);
			}

			// 事务处理
			boolean succeed = false;
//            try{
			succeed = Db.tx(new IAtom() {
				@Override
				public boolean run() throws SQLException {
					// 主表
					if (!Db.save("movetasktable", movetasktable)) {
						log.info("保存主表信息失败");
						result.put("info", "保存主表信息失败");
						return false;
					}
					// 历史表
					if (!Db.save("JBPM4_OAS_PROCESS_HISTORY", jbpm4_oas_process_history)) {
						log.info("保存历史表信息失败");
						result.put("info", "保存历史表信息失败");
						return false;
					}
					// 需要领导审批为是，写暂存表、任务表写领导信息
					// 不需要领导审批否，直接写子表、任务表写执行人和抄送人信息
					if ("是".equals(order.getIsneedleaderuser()) || "true".equals(order.getIsneedleaderuser())) {
						// 任务表---领导
						if (!Db.save("tasknew", getLeaterRecord(order, mainId, no, currentDate))) {
							log.info("保存任务表信息失败");
							result.put("info", "保存任务表信息失败");
							return false;
						}
						// 暂存表---执行人
						for (Record executorRecord : getExecutorRecord(order.getExecutor(), mainId)) {
							if (!Db.save("movetasktableper", executorRecord)) {
								log.info("执行人保存暂存表-信息失败");
								result.put("info", "保存暂存表-信息失败");
								return false;
							}
						}
						// 暂存表---抄送人
						for (Record copytorRecord : getCopytorRecord(order.getCopytor(), mainId)) {
							if (!Db.save("movetasktableper", copytorRecord)) {
								log.info("抄送人保存暂存表-信息失败");
								result.put("info", "抄送人保存暂存表-信息失败");
								return false;
							}
						}
					} else {
						// 子表---执行人//子表---抄送人
						for (Record subtable : movetasktableprocessRecords) {
							if (!Db.save("movetasktableprocess", subtable)) {
								log.info("保存子表--信息失败");
								result.put("info", "保存子表--信息失败");
								return false;
							}
						}
						// 任务表---执行人//任务表---抄送人
						for (Record tasknew : tasknewRecords) {
							if (!Db.save("tasknew", tasknew)) {
								log.info("保存任务表--信息失败");
								result.put("info", "保存任务表--信息失败");
								return false;
							}
						}
					}
					return true;
				}
			});
			result.put("success", succeed);
			result.put("no", no);
			result.put("info", "执行成功");

			try {
				notifyDingTalkService.notify(mainId + "", JSON.toJSONString(notifyBody));
			} catch (Exception e) {
				// 通知失败时，返回的创建订单是成功，但是提示发送消息失败
				log.error(e.getMessage(), e);
				result.put("success", true);
				result.put("info", e.getMessage());
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			result.put("success", false);
			result.put("info", e.getMessage());
		}

		return result;
	}

	// 修改
	// 1、删除暂存表数据MAINTICKETID
	// 2、删除任务表
	// 3、删除子表
	// 4、更新主表数据
	// 5、插入历史表
	// 6、插入暂存表
	// 7、插入任务表
	public Map<String, Object> update(Order order) {
		Map<String, Object> result = new HashMap<>();
		try {
			// 通过账号查询出用户信息
			Record userinfo = getUsersListByUserName(order.getProposeruser());

			Long mainId = order.getId();
			// 创建主表NO
			String no = getNo(order.getNetType(), userinfo.getStr("LOCATIONID"));
			// 创建时间和申请时间
			Date currentDate = new Date();
			// 主表信息--1、填的信息 和选的审核人信息 存在主表-
			Record movetasktable = getMovetasktable(order, userinfo, mainId, currentDate, no);
			// 2、选的执行人抄送人存在暂存表---movetasktableper
			// 直接写到了事务里
			// 3、记录表---JBPM4_OAS_PROCESS_HISTORY
			// n.getCopyToName()+"提交任务到"+n.getProposerName()+";抄送人意见："+n.getCopyToOpinion()
			// 与文档不一致todo
			String COMMENT_ = "";
			if ("是".equals(order.getIsneedleaderuser())) {
				COMMENT_ = userinfo.getStr("NAME") + "修改工单到" + order.getLeadername();
			} else {
				COMMENT_ = userinfo.getStr("NAME") + "修改工单";
			}
			// 传输//公客 //动环 //建设//政企 //数据 //无线 //核心网//监控//线路//综合维护
			Record jbpm4_oas_process_history = getJbpm4OasProcessHistory(order, userinfo, COMMENT_, mainId);

			// 4、我的任务表---tasknew--
			// 4.1-领导审核写领导
			// 4.2-无领导审核写执行人
			/// moveTaskTable/leaderPage 领导审核页面URL
			/// moveTaskTable/executerPage 执行人执行页面URL
			/// moveTaskTable/copyToPage 抄送人执行页面URL
			/// moveTaskTable/closePage 工单关闭页面URL
			/// moveTaskTable/againMoveTaskTable 再次发起工单页面URL
			// 直接写到了事务方法中

			// 5、子表--movetasktableprocess
			List<Record> movetasktableprocessRecords = new ArrayList<>();
			// 4.2-无领导审核写执行人任务表记录
			List<Record> tasknewRecords = new ArrayList<>();
			if ("否".equals(order.getIsneedleaderuser()) || "false".equals(order.getIsneedleaderuser())) {
				if (order.getExecutor() != null) {
					for (Executor executor : order.getExecutor()) {
						Record movetasktableprocess = getMovetasktableprocessForExecutor(order, userinfo, mainId,
								currentDate, no, executor);
						movetasktableprocessRecords.add(movetasktableprocess);
						// 添加执行人，执行人需要子表ID，所以写在这
						tasknewRecords.add(getExecutorTaskRecord(order, executor, movetasktableprocess.get("ID"), no,
								currentDate));
					}
				}
				if (order.getCopytor() != null) {
					for (Copytor copytor : order.getCopytor()) {
						Record movetasktableprocess = getMovetasktableprocessForCopytor(order, userinfo, mainId,
								currentDate, no, copytor);
						movetasktableprocessRecords.add(movetasktableprocess);
						// 添加执行人，执行人需要子表ID，所以写在这
						tasknewRecords.add(
								getCopytorTaskRecord(order, copytor, movetasktableprocess.get("ID"), no, currentDate));
					}
				}
			}

			/////////////////////////////////////////////////////////////////////
			// 查询子表ID
			List<Record> subInfos = Db.find("select * from movetasktableprocess where MAINTICKETID = ?", order.getId());
			// 事务处理
			boolean succeed = false;
//            try{
			succeed = Db.tx(new IAtom() {
				@Override
				public boolean run() throws SQLException {

					// 1、删除暂存表数据MAINTICKETID
					int deletemovetasktableper = Db.delete("delete from movetasktableper where MAINTICKETID = ?",
							order.getId());
					// 2、删除任务表
					int deletetasknew = Db.delete("delete from tasknew where TICKETID = ?", order.getId());
					// 有可能没有审核，直接写到子表中，然后任务表里记的是子表的ID，没会写in 的sql,只能循环
					for (Record sub : subInfos) {
						if (Db.delete("delete from tasknew where TICKETID = ?", sub.getLong("ID")) == 0) {
							log.info("删除任务表--信息失败");
							result.put("info", "删除任务表--信息失败");
							return false;
						}
					}
					// 3、删除子表
					int deletemovetasktableprocess = Db
							.delete("delete from movetasktableprocess where MAINTICKETID = ?", order.getId());
					// 主表
					if (!Db.update("movetasktable", movetasktable)) {
						log.info("更新主表--信息失败");
						result.put("info", "更新主表--信息失败");
						return false;
					}
					// 历史表
					if (!Db.save("JBPM4_OAS_PROCESS_HISTORY", jbpm4_oas_process_history)) {
						log.info("插入历史表--信息失败");
						result.put("info", "插入历史表--信息失败");
						return false;
					}
					// 需要领导审批为是，写暂存表、任务表写领导信息
					// 不需要领导审批否，直接写子表、任务表写执行人和抄送人信息
					if ("是".equals(order.getIsneedleaderuser())) {
						// 任务表---领导
						if (!Db.save("tasknew", getLeaterRecord(order, mainId, no, currentDate))) {
							log.info("插入任务表--信息失败");
							result.put("info", "插入任务表--信息失败");
							return false;
						}
						// 暂存表---执行人
						for (Record executorRecord : getExecutorRecord(order.getExecutor(), mainId)) {
							if (!Db.save("movetasktableper", executorRecord)) {
								log.info("插入暂存表--信息失败");
								result.put("info", "插入暂存表--信息失败");
								return false;
							}
						}
						// 暂存表---抄送人
						for (Record copytorRecord : getCopytorRecord(order.getCopytor(), mainId)) {
							if (!Db.save("movetasktableper", copytorRecord)) {
								log.info("插入暂存表--信息失败");
								result.put("info", "插入暂存表--信息失败");
								return false;
							}
						}
					} else {
						// 子表---执行人//子表---抄送人
						for (Record subtable : movetasktableprocessRecords) {
							if (!Db.save("movetasktableprocess", subtable)) {
								log.info("插入子表--信息失败");
								result.put("info", "插入子表--信息失败");
								return false;
							}
						}
						// 任务表---执行人//任务表---抄送人
						for (Record tasknew : tasknewRecords) {
							if (!Db.save("tasknew", tasknew)) {
								log.info("插入任务表--信息失败");
								result.put("info", "插入任务表--信息失败");
								return false;
							}
						}
					}
					result.put("success", true);
					return true;
				}
			});
//            }catch (Exception e){
//                log.error("",e);
//                succeed = false;
//            }
			result.put("success", succeed);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			result.put("success", false);
			result.put("info", e.getMessage());
		}

		return result;
	}

	private Record getUsersListByUserName(String userName) {
		List<Record> users = Db.find(
				"SELECT a.LOCATIONID AS location ,a.NAME AS NAME,a.MOBILE AS mobile ,a.EMAIL AS email,d.ID AS departId,d.NAME AS departName from app_user a\n"
						+ "inner JOIN app_department d\n" + "ON a.DEPARTMENT_ID=d.ID\n" + "WHERE a.USERNAME=  ? ",
				userName);
		Record userinfo = null;
		if (users.size() > 0) {
			userinfo = users.get(0);
		}
		return userinfo;
	}

	private List<Record> getAuditAfterTaskRecord(List<Record> movetasktableprocessList) {
		List<Record> tasknewList = new ArrayList<>();
		for (Record sub : movetasktableprocessList) {
			Record tasknew = new Record().set("ID", getSqu()).set("CREATEDATE", sub.getDate("CREATEDATE"))
					.set("NO", sub.getStr("NO"))
					.set("PROCESSINGUSERNAMES",
							StrUtil.isEmpty(sub.getStr("EXECUTORUSER")) ? sub.getStr("COPYTONAME")
									: sub.getStr("EXECUTORNAME"))
					.set("PROCESSINGUSERS",
							StrUtil.isEmpty(sub.getStr("EXECUTORUSER")) ? sub.getStr("COPYTOUSER")
									: sub.getStr("EXECUTORUSER"))
					.set("STATUS", sub.getStr("ACTIVITYNAME")).set("THEME", sub.getStr("THEME"))
					.set("TICKETID", sub.getStr("ID"))
					.set("URI", StrUtil.isEmpty(sub.getStr("EXECUTORUSER")) ? "/moveTaskTable/copyToPage"
							: "/moveTaskTable/executerPage");
			tasknewList.add(tasknew);
		}
		return tasknewList;

	}

	// 转派、执行人，抄送人
	// Operator 前台传的对象
	// subId 子表ID
	// taskRecord 原任务表数据
	// type ture为执行人 false为抄送人
	private Record getTaskRecordByTaskRecord(String user, String username, Long subId, Record taskRecord,
			boolean type) {
		return new Record().set("ID", getSqu()).set("CREATEDATE", new Date()).set("NO", taskRecord.get("NO"))
				.set("PROCESSINGUSERNAMES", username).set("PROCESSINGUSERS", user)
				.set("STATUS", taskRecord.get("STATUS")).set("THEME", taskRecord.get("THEME")).set("TICKETID", subId)
				.set("URI", type ? "moveTaskTable/executerPage" : "moveTaskTable/copyToPage");
	}

	// 无审核人时，获取执行人记录
	private Record getExecutorTaskRecord(Order order, Executor executor, Long subId, String no, Date currentDate) {
		return new Record().set("ID", getSqu()).set("CREATEDATE", currentDate).set("NO", no)
				.set("PROCESSINGUSERNAMES", executor.getProcessingusername())
				.set("PROCESSINGUSERS", executor.getProcessinguser()).set("STATUS", "待执行")
				.set("THEME", order.getTheme()).set("TICKETID", subId).set("URI", "moveTaskTable/executerPage");
	}

	// 无审核人时，获取抄送人的记录
	private Record getCopytorTaskRecord(Order order, Copytor copytor, Long subId, String no, Date currentDate) {
		return new Record().set("ID", getSqu()).set("CREATEDATE", currentDate).set("NO", no)
				.set("PROCESSINGUSERNAMES", copytor.getProcessingusername())
				.set("PROCESSINGUSERS", copytor.getProcessinguser()).set("STATUS", "待配合").set("THEME", order.getTheme())
				.set("TICKETID", subId).set("URI", "moveTaskTable/copyToPage");
	}

	// 获取需要审核时任务表数据
	private Record getLeaterRecord(Order order, Long mainId, String no, Date currentDate) {
		return new Record().set("ID", getSqu()).set("CREATEDATE", currentDate).set("NO", no)
				.set("PROCESSINGUSERNAMES", order.getLeadername()).set("PROCESSINGUSERS", order.getLeaderuser())
				.set("STATUS", "待审核").set("THEME", order.getTheme()).set("TICKETID", mainId)
				.set("URI", "moveTaskTable/leaderPage");

	}

	// 创建时获取历史表数据
	private Record getJbpm4OasProcessHistory(Order order, Record userinfo, String COMMENT_, Long mainId) {
		Record jbpm4_oas_process_history = new Record().set("ID", getSqu())
				.set("ACTIVITYNAME", "是".equals(order.getIsneedleaderuser()) ? "待审核" : "待执行").set("COMMENT_", COMMENT_)
				.set("CREATETIME", new Date()).set("ISSINGLEOPERATION", "1")
				.set("OPERATORDEPID", userinfo.getStr("departId")).set("OPERATORDEPNAME", userinfo.getStr("departName"))
				.set("OPERATORLOCATIONID", userinfo.getStr("LOCATIONID"))
				.set("OPERATORLOCATIONSTR", LocationEnum.getName(userinfo.getStr("LOCATIONID")))
				.set("OPERATORNAME", userinfo.getStr("NAME"))
				.set("OPERATORSPECIALTY", SpecialtyEnum.getName(order.getTroublespecialty()))// ?????
				.set("OPERATORSPECIALTYSTR", order.getTroublespecialty())// ?????
				.set("OPERATORTEL", userinfo.getStr("mobile")).set("OPERATORUSERNAME", order.getProposeruser())
				.set("TICKETID", mainId)// 主表id
				.set("TRANSITION", "修改工单").set("VERSION", "0");
		return jbpm4_oas_process_history;
	}

//-----------------------------------------------
	// 审核时获取历史表数据
	private Record getJbpm4OasProcessHistoryForAudit(Record order, Record userinfo, StatusEnum statusEnum,
			String commont) {
		Record jbpm4_oas_process_history = new Record().set("ID", getSqu())
				.set("ACTIVITYNAME", statusEnum.getActivitname())// ----
				.set("COMMENT_", userinfo.getStr("NAME") + commont).set("CREATETIME", new Date())
				.set("ISSINGLEOPERATION", "1").set("OPERATORDEPID", userinfo.get("departId"))
				.set("OPERATORDEPNAME", userinfo.getStr("departName"))
				.set("OPERATORLOCATIONID", userinfo.getStr("LOCATIONID"))
				.set("OPERATORLOCATIONSTR", LocationEnum.getName(userinfo.getStr("LOCATIONID")))
				.set("OPERATORNAME", userinfo.getStr("NAME")).set("OPERATORSPECIALTY", order.get("OPERATORSPECIALTY"))
				.set("OPERATORSPECIALTYSTR", order.get("OPERATORSPECIALTYSTR"))
				.set("OPERATORTEL", userinfo.getStr("mobile")).set("OPERATORUSERNAME", order.getStr("OPERATORUSERNAME"))
				.set("TICKETID", order.get("ID"))// 主表id
				.set("TRANSITION", statusEnum.getTransition())// ----
				.set("VERSION", "0");
		return jbpm4_oas_process_history;
	}

	SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");// 注意月份是MM

	private Date getDateByString(String d) {
		Date feedbacktime = null;
		try {
			feedbacktime = sf.parse(d);
		} catch (ParseException e) {
			log.error("", e);
			return null;
		}
		return feedbacktime;
	}

	// 获取主表信息
	private Record getMovetasktable(Order order, Record userinfo, Long mainId, Date currentDate, String no) {

		Record movetasktable = new Record().set("ID", mainId).set("NO", no)
				.set("ACTIVITYNAME", "是".equals(order.getIsneedleaderuser()) ? "待审核" : "待执行")// 当前活动
				.set("TROUBLESPECIALTY", order.getTroublespecialty())// 专业
				.set("STARTCITY", LocationEnum.getName(userinfo.getStr("LOCATIONID")))// 发起地市
				.set("CREATORNAME", userinfo.getStr("NAME"))// 发起人
				.set("CREATORTEL", userinfo.getStr("mobile"))// 发起电话
				.set("THEME", order.getTheme())// 主题
				.set("FEEDBACKTIME", getDateByString(order.getFeedbacktime()))// 要求完成时间
				.set("SUMMARY", order.getSummary())// 任务摘要
				.set("CREATETIME", currentDate)// 创建时间
				.set("PROCESSINGUSERS", "是".equals(order.getIsneedleaderuser()) ? order.getLeaderuser() : "")// 当前处理人账号
				.set("PROCESSINGUSERNAMES", "是".equals(order.getIsneedleaderuser()) ? order.getLeadername() : "")// 当前处理人姓名
				.set("PROPOSERUSER", order.getProposeruser())// 申请人账号
				.set("PROPOSERNAME", userinfo.getStr("NAME"))// 申请人
				.set("PROPOSEREMAL", userinfo.getStr("email"))// 申请人邮箱
				.set("PROPOSERPHONE", userinfo.getStr("mobile"))// 申请人电话
				.set("DEPARTMENTID", userinfo.getStr("departId"))// 部门ID
				.set("DEPARTMENTNAME", userinfo.getStr("departName"))// 部门名称
				.set("PROPOSERDATE", currentDate)// 申请时间
				.set("ISNEEDLEADERUSER", order.getIsneedleaderuser() == null ? "否" : order.getIsneedleaderuser())// 是否需要领导审核
				.set("LEADERUSER", order.getLeaderuser())// 省领导账号
				.set("LEADERNAME", order.getLeadername())// 省领导姓名
				.set("RENWUGUILEI", order.getRenwuguilei());// 任务归类
		return movetasktable;
	}

	// 通过子表获取子表列表信息--用于转派执行或转派抄送
	// movetasktableproces:原子表信息
	// operator:传入的对象
	// type:ture为执行人转派，false为抄送人转派
	private List<Record> getMovetasktableprocesByMovetasktableprocesList(Record movetasktableproces, Operator operator,
			boolean type) {
		List<Record> resultList = new ArrayList<>();
		if (type) {
			for (Executor executor : operator.getExecutor()) {
				resultList.add(getMovetasktableprocesByMovetasktableproces(movetasktableproces,
						executor.getProcessinguser(), executor.getProcessingusername(), type));
			}
		} else {
			for (Copytor copytor : operator.getCopytor()) {
				resultList.add(getMovetasktableprocesByMovetasktableproces(movetasktableproces,
						copytor.getProcessinguser(), copytor.getProcessingusername(), type));
			}
		}
		return resultList;
	}

	// 通过子表获取子表信息--用于转派执行或转派抄送
	// movetasktableproces:原子表信息
	// operator:传入的对象
	// type:ture为执行人转派，false为抄送人转派
	private Record getMovetasktableprocesByMovetasktableproces(Record movetasktableproces, String user, String username,
			boolean type) {
		long subId = getSqu();
		Record movetasktableprocess = new Record().set("ID", subId).set("NO", movetasktableproces.get("NO"))
				.set("ACTIVITYNAME", movetasktableproces.get("ACTIVITYNAME"))// 当前活动
				.set("STARTCITY", movetasktableproces.get("STARTCITY"))// 发起地市
				.set("TROUBLESPECIALTY", movetasktableproces.get("TROUBLESPECIALTY"))// 专业
				.set("CREATORNAME", movetasktableproces.get("CREATORNAME"))// 发起人
				.set("CREATORTEL", movetasktableproces.get("CREATORTEL"))// 发起电话
				.set("THEME", movetasktableproces.get("THEME"))// 主题
				.set("FEEDBACKTIME", movetasktableproces.get("FEEDBACKTIME"))// 要求完成时间
				.set("SUMMARY", movetasktableproces.get("SUMMARY"))// 任务摘要
				.set("CREATETIME", new Date())// 创建时间
				.set("PROCESSINGUSERS", movetasktableproces.get("PROCESSINGUSERS"))// 当前处理人账号
				.set("PROCESSINGUSERNAMES", movetasktableproces.get("PROCESSINGUSERNAMES"))// 当前处理人姓名
				.set("PROCESSEDUSERS", "")// 过去处理人账号
				.set("PROCESSEDUSERNAMES", "")// 过去处理人姓名
				.set("MAINTICKETID", movetasktableproces.get("MAINTICKETID")).set("EXECUTORUSER", type ? user : "")// 执行人时写
				.set("EXECUTORNAME", type ? username : "")// 执行人时写
				.set("CITYNAME", movetasktableproces.get("CITYNAME")).set("COPYTOUSER", type ? "" : user)// 抄送人时写
				.set("COPYTONAME", type ? "" : username)// 抄送人时写
				.set("REDEPLOYUSER", "")// 转派人时写
				.set("REDEPLOYNAME", "");// 转派人时写
		return movetasktableprocess;
	}

	// 通过执行人获取子表信息
	private Record getMovetasktableprocessForExecutor(Order order, Record userinfo, Long mainId, Date currentDate,
			String no, Executor executor) {
		long subId = getSqu();
		Record movetasktableprocess = new Record().set("ID", subId).set("NO", no).set("ACTIVITYNAME", "待执行")// 当前活动
				.set("STARTCITY", LocationEnum.getName(userinfo.getStr("LOCATIONID")))// 发起地市
				.set("TROUBLESPECIALTY", order.getTroublespecialty())// 专业
				.set("CREATORNAME", userinfo.getStr("NAME"))// 发起人
				.set("CREATORTEL", userinfo.getStr("mobile"))// 发起电话
				.set("THEME", order.getTheme())// 主题
				.set("FEEDBACKTIME", getDateByString(order.getFeedbacktime()))// 要求完成时间
				.set("SUMMARY", order.getSummary())// 任务摘要
				.set("CREATETIME", currentDate)// 创建时间
				.set("PROCESSINGUSERS", executor.getProcessinguser())// 当前处理人账号
				.set("PROCESSINGUSERNAMES", executor.getProcessingusername())// 当前处理人姓名
				.set("PROCESSEDUSERS", "")// 过去处理人账号
				.set("PROCESSEDUSERNAMES", "")// 过去处理人姓名
				.set("MAINTICKETID", mainId).set("EXECUTORUSER", executor.getProcessinguser())// 执行人时写
				.set("EXECUTORNAME", executor.getProcessingusername())// 执行人时写
				.set("CITYNAME", executor.getStation()).set("COPYTOUSER", "")// 抄送人时写
				.set("COPYTONAME", "")// 抄送人时写
				.set("REDEPLOYUSER", "")// 转派人时写
				.set("REDEPLOYNAME", "");// 转派人时写
		return movetasktableprocess;
	}

	// 通过抄送人获取子表信息
	private Record getMovetasktableprocessForCopytor(Order order, Record userinfo, Long mainId, Date currentDate,
			String no, Copytor copytor) {
		long subId = getSqu();
		Record movetasktableprocess = new Record().set("ID", subId).set("NO", no).set("ACTIVITYNAME", "待配合")// 当前活动
				.set("STARTCITY", LocationEnum.getName(userinfo.getStr("LOCATIONID")))// 发起地市
				.set("TROUBLESPECIALTY", order.getTroublespecialty())// 专业
				.set("CREATORNAME", userinfo.getStr("NAME"))// 发起人
				.set("CREATORTEL", userinfo.getStr("mobile"))// 发起电话
				.set("THEME", order.getTheme())// 主题
				.set("FEEDBACKTIME", getDateByString(order.getFeedbacktime()))// 要求完成时间
				.set("SUMMARY", order.getSummary())// 任务摘要
				.set("CREATETIME", currentDate)// 创建时间
				.set("PROCESSINGUSERS", copytor.getProcessinguser())// 当前处理人账号
				.set("PROCESSINGUSERNAMES", copytor.getProcessingusername())// 当前处理人姓名
				.set("PROCESSEDUSERS", "")// 过去处理人账号
				.set("PROCESSEDUSERNAMES", "")// 过去处理人姓名
				.set("MAINTICKETID", mainId)
//                .set("EXECUTORUSER","")//执行人时写
//                .set("EXECUTORNAME","")//执行人时写
				.set("CITYNAME", copytor.getStation())// 执行人时写
				.set("COPYTOUSER", copytor.getProcessinguser())// 抄送人时写
				.set("COPYTONAME", copytor.getProcessingusername())// 抄送人时写
				.set("REDEPLOYUSER", "")// 转派人时写
				.set("REDEPLOYNAME", "");// 转派人时写
		return movetasktableprocess;
	}

	// 通过暂存表获取子表信息
	private List<Record> getMovetasktableprocessForMovetasktableper(Record order, List<Record> movetasktablepers) {
		List<Record> movetasktableprocessList = new ArrayList<>();
		for (Record movetasktableperRecord : movetasktablepers) {
			long subId = getSqu();
			boolean type = "执行".equals(movetasktableperRecord.get("TASKTYPE"));
			Record movetasktableprocess = new Record().set("ID", subId).set("NO", order.getStr("NO"))
					.set("ACTIVITYNAME", type ? "待执行" : "待配合")// 当前活动
					.set("STARTCITY", order.getStr("STARTCITY"))// 发起地市type
					.set("TROUBLESPECIALTY", order.getStr("TROUBLESPECIALTY"))// 专业
					.set("CREATORNAME", order.getStr("CREATORNAME"))// 发起人
					.set("CREATORTEL", order.getStr("CREATORTEL"))// 发起电话
					.set("THEME", order.getStr("THEME"))// 主题
					.set("FEEDBACKTIME", order.getDate("FEEDBACKTIME"))// 要求完成时间
					.set("SUMMARY", order.getStr("SUMMARY"))// 任务摘要
					.set("CREATETIME", order.getDate("CREATETIME"))// 创建时间
					.set("PROCESSINGUSERS", movetasktableperRecord.get("PROCESSINGUSER"))// 当前处理人账号
					.set("PROCESSINGUSERNAMES", movetasktableperRecord.get("PROCESSINGUSERNAME"))// 当前处理人姓名
					.set("PROCESSEDUSERS", "")// 过去处理人账号
					.set("PROCESSEDUSERNAMES", "")// 过去处理人姓名
					.set("MAINTICKETID", order.get("ID"))
					.set("EXECUTORUSER", type ? movetasktableperRecord.get("PROCESSINGUSER") : "")// 执行人时写
					.set("EXECUTORNAME", type ? movetasktableperRecord.get("PROCESSINGUSERNAME") : "")// 执行人时写
					.set("CITYNAME", type ? movetasktableperRecord.get("CITY") : "")// 执行人时写
					.set("COPYTOUSER", type ? "" : movetasktableperRecord.get("PROCESSINGUSER"))// 抄送人时写
					.set("COPYTONAME", type ? "" : movetasktableperRecord.get("PROCESSINGUSERNAME"))// 抄送人时写
					.set("REDEPLOYUSER", "")// 转派人时写
					.set("REDEPLOYNAME", "");// 转派人时写

			movetasktableprocessList.add(movetasktableprocess);
		}

		return movetasktableprocessList;
	}

	// 审批
	// 1、更新主表数据
	// 2、移动暂存表到子表
	// 3、插入历史表
	// 4、更新我的任务表
	// 4-1、删除审核的任务表信息
	// 4-2、插入执行人和抄送人的任务表信息
	public Map<String, Object> audit(AuditOrder order) {
		Map<String, Object> result = new HashMap<>();
		try {
			// 1、更新主表数据
			Record movetasktable = Db.findById("movetasktable", order.getId());
			String updatemain = "update movetasktable set ISLEADERPASS=?, LEADEROPINION = ?, PROCESSEDUSERS = ? "
					+ ", PROCESSEDUSERNAMES = ?, ACTIVITYNAME=?,LEADERDATE = ?,EXECUTORUSER=?,EXECUTORNAME=? where id = ?";
			// 2、移动暂存表到子表
			List<Record> movetasktablepers = Db.find("select * from movetasktableper where MAINTICKETID = ?",
					order.getId());
			List<Record> movetasktableprocessList = getMovetasktableprocessForMovetasktableper(movetasktable,
					movetasktablepers);
			// 3、插入历史表
			Record audituserinfo = getUsersListByUserName(order.getLeaderuser());
			Record jbpm4OasProcessHistoryForAudit = getJbpm4OasProcessHistoryForAudit(movetasktable, audituserinfo,
					StatusEnum.AUIDT, "审核通过");
			// 4、更新我的任务表
			// 4-1、删除审核的任务表信息
			// 4-2、插入执行人和抄送人的任务表信息
			List<Record> tasknewList = getAuditAfterTaskRecord(movetasktableprocessList);
			// 事务处理
			boolean succeed = false;
//            try{
			succeed = Db.tx(new IAtom() {
				@Override
				public boolean run() throws SQLException {
					// 更新主表
					int movetasktableResult = Db.update(updatemain, order.getIsleaderpass(), order.getLeaderopinion(),
							movetasktable.get("PROCESSEDUSERS") + order.getLeaderuser(),
							movetasktable.get("PROCESSEDUSERNAMES") + order.getLeadername(),
							"是".equals(order.getIsleaderpass()) ? "待执行" : "待重新发起-被驳回", new Date(),
							movetasktable.get("EXECUTORUSER") + order.getLeaderuser(),
							movetasktable.get("EXECUTORNAME") + order.getLeadername(), order.getId());
					// 插入历史表
					if (!Db.save("JBPM4_OAS_PROCESS_HISTORY", jbpm4OasProcessHistoryForAudit)) {
						log.info("插入历史表--信息失败");
						result.put("info", "插入历史表--信息失败");
						return false;
					}

					// 4-1、删除审核的任务表信息
					if (Db.delete("delete from tasknew where TICKETID = ?", order.getId()) < 1) {
						log.info("删除任务表--信息失败");
						result.put("info", "删除任务表---信息失败");
						return false;
					}
					if ("是".equals(order.getIsleaderpass())) {
						// 插入子表
						for (Record subtable : movetasktableprocessList) {
							if (!Db.save("movetasktableprocess", subtable)) {
								log.info("插入子表--信息失败");
								result.put("info", "插入子表--信息失败");
								return false;
							}
						}
						// 4-2、插入执行人和抄送人的任务表信息
						for (Record tasknew : tasknewList) {
							if (!Db.save("tasknew", tasknew)) {
								log.info("插入任务表--信息失败");
								result.put("info", "插入任务表--信息失败");
								return false;
							}
						}
					}

					result.put("success", true);
					return true;
				}
			});

			result.put("success", succeed);
		} catch (Exception e) {
			log.error("", e);
			System.out.println(e.getMessage());
			result.put("success", false);
			result.put("info", e.getMessage());
		}

		return result;

	}

	// 关闭
	// 1、修改主表状态
	// 2、修改子表状态---没有发现要处理的，好像不更新
	// 3、添加历史表
	// 4、删除任务表
	public Map<String, Object> close(Operator operator) {
		Map<String, Object> result = new HashMap<>();
		try {
			// 1、修改主表状态
			Record movetasktable = Db.findById("movetasktable", operator.getId());
			String updatemain = "update movetasktable set ACTIVITYNAME=?, CLOSETIME = ?" + " where id = ?";
			// 3、添加历史表
			// 通过订单信息获取执行人信息
			Record operatorInfo = getUsersListByUserName(movetasktable.getStr("PROPOSERUSER"));
			Record jbpm4OasProcessHistoryForClose = getJbpm4OasProcessHistoryForAudit(movetasktable, operatorInfo,
					StatusEnum.CLOSE, "关闭单据");

			// 事务处理,
			boolean succeed = false;
//            try{
			succeed = Db.tx(new IAtom() {
				@Override
				public boolean run() throws SQLException {
					// 更新主表
					if (Db.update(updatemain, "已关闭", new Date(), operator.getId()) < 1) {
						log.info("更新主表--信息失败");
						result.put("info", "更新主表--信息失败");
						return false;
					}
					// 插入历史表
					if (!Db.save("JBPM4_OAS_PROCESS_HISTORY", jbpm4OasProcessHistoryForClose)) {
						log.info("插入历史表--信息失败");
						result.put("info", "插入历史表--信息失败");
						return false;
					}

					// 4、删除任务表
					Db.delete("delete from tasknew where NO = ? ", movetasktable.getStr("NO"));

					result.put("success", true);
					return true;
				}
			});
			result.put("success", succeed);
		} catch (Exception e) {
			log.error("", e);
			System.out.println(e.getMessage());
			result.put("success", false);
			result.put("info", e.getMessage());
		}
		return result;

	}

	// 执行人执行单据
	// 1、修改主表状态
	// 2、修改子表状态
	// 3、添加历史表
	// 4、删除任务表
	public Map<String, Object> execute(Operator operator) {
		Map<String, Object> result = new HashMap<>();
		// 1、修改主表状态
		Record movetasktable = Db.findById("movetasktable", operator.getId());
		String updatemain = "update movetasktable set ACTIVITYNAME=? ,PROCESSEDUSERS=?,PROCESSEDUSERNAMES=?"
				+ " where id = ?";
		// 3、添加历史表
		Record operatorInfo = getUsersListByUserName(operator.getProcessinguser());
		Record jbpm4OasProcessHistoryForClose = getJbpm4OasProcessHistoryForAudit(movetasktable, operatorInfo,
				StatusEnum.EXECUTE, "执行意见：已完成");
		// 2、修改子表状态
		Record movetasktableprocessInfo = Db.findById("movetasktableprocess ", operator.getSid());
		// 事务处理,
		boolean succeed = false;
		try {
			succeed = Db.tx(new IAtom() {
				@Override
				public boolean run() throws SQLException {
					// 更新主表
					if (Db.update(updatemain, "待关闭",
							movetasktable.get("PROCESSEDUSERS") + ";" + operator.getProcessinguser(),
							movetasktable.get("PROCESSEDUSERNAMES") + ";" + operatorInfo.get("NAME"),
							operator.getId()) < 1) {
						log.info("更新主表--信息失败");
						result.put("info", "更新主表--信息失败");
						return false;
					}
					// 插入历史表
					if (!Db.save("JBPM4_OAS_PROCESS_HISTORY", jbpm4OasProcessHistoryForClose)) {
						log.info("插入历史表--信息失败");
						result.put("info", "插入历史表--信息失败");
						return false;
					}
					// 修改子表状态
					Record movetasktableprocess = Db
							.findById("movetasktableprocess", movetasktableprocessInfo.get("ID"))
							.set("ACTIVITYNAME", "已反馈").set("EXECUTOROPINION", operator.getExecutoropinion())
							.set("SJFEEDBACKTIME", operator.getFeedbacktime()).set("EXECUTORDATE", new Date());
					if (!Db.update("movetasktableprocess", movetasktableprocess)) {
						log.info("修改子表--信息失败");
						result.put("info", "修改子表--信息失败");
						return false;
					}

					// 4、删除任务表
					if (Db.delete("delete from tasknew where TICKETID = ? and PROCESSINGUSERS=?",
							movetasktableprocessInfo.get("ID"), operator.getProcessinguser()) < 1) {
						log.info("删除任务表--信息失败");
						result.put("info", "删除任务表--信息失败");
						return false;
					}
					return true;
				}
			});
		} catch (Exception e) {
			log.info("执行--信息失败");
			succeed = false;
			result.put("info", e.getMessage());
		}

		result.put("success", succeed);
		return result;
	}

	// 抄送人执行单据
	// 1、修改主表状态
	// 2、修改子表状态
	// 3、添加历史表
	// 4、删除任务表
	public Map<String, Object> copyHandle(Operator operator) {
		Map<String, Object> result = new HashMap<>();
		// 1、修改主表状态
		Record movetasktable = Db.findById("movetasktable", operator.getId());
		String updatemain = "update movetasktable set PROCESSEDUSERS=?,PROCESSEDUSERNAMES=?" + " where id = ?";
		// 3、添加历史表
		Record operatorInfo = getUsersListByUserName(operator.getProcessinguser());
		Record jbpm4OasProcessHistoryForClose = getJbpm4OasProcessHistoryForAudit(movetasktable, operatorInfo,
				StatusEnum.COPY, "抄送人意见：已完成");
		// 2、修改子表状态
//        Record movetasktableprocessInfo = Db.findFirst("select * from movetasktableprocess where MAINTICKETID = ? and EXECUTORUSER = ?",operator.getId(),operator.getProcessinguser());
		Record movetasktableprocessInfo = Db.findById("movetasktableprocess ", operator.getSid());
		// 事务处理,
		boolean succeed = false;
		try {
			succeed = Db.tx(new IAtom() {
				@Override
				public boolean run() throws SQLException {
					// 更新主表
					int movetasktableResult = Db.update(updatemain,
							movetasktable.get("PROCESSEDUSERS") + ";" + operator.getProcessinguser(),
							movetasktable.get("PROCESSEDUSERNAMES") + ";" + operatorInfo.get("NAME"), operator.getId());
					// 插入历史表
					if (!Db.save("JBPM4_OAS_PROCESS_HISTORY", jbpm4OasProcessHistoryForClose)) {
						return false;
					}
					// 修改子表状态
					Record movetasktableprocess = Db
							.findById("movetasktableprocess", movetasktableprocessInfo.get("ID"))
							.set("ACTIVITYNAME", "已配合").set("COPYTOOPINION", operator.getExecutoropinion())
							.set("COPYTODATE", new Date());
					Db.update("movetasktableprocess", movetasktableprocess);

					// 4、删除任务表
					int deletetasknew = Db.delete("delete from tasknew where TICKETID = ? and PROCESSINGUSERS=?",
							movetasktableprocessInfo.getStr("ID"), operator.getProcessinguser());

					return deletetasknew == 1;
				}
			});
		} catch (Exception e) {
			log.info("执行--信息失败");
			succeed = false;
			result.put("info", e.getMessage());
		}

		result.put("success", succeed);
		return result;
	}

	private String notifyDing(String mainID, Operator operator, boolean isExecutor) {
		// 调用通知接口数据
		Map<String, Object> notifyBody = new HashMap<>();
		notifyBody.put("process_type",
				isExecutor ? ProcessType.MAIN_WAITING_EXECUTE : ProcessType.SUB_WAITING_COOPERATE);
		List<Map<String, String>> users = new ArrayList<>();
		if (isExecutor) {
			for (Executor executor : operator.getExecutor()) {
				Record userinfo = getUsersListByUserName(executor.getProcessinguser());
				Map<String, String> notifyuser = new HashMap<>();
				notifyuser.put("phone_number", userinfo.getStr("mobile"));
				notifyuser.put("activity_type",
						isExecutor ? ProcessType.MAIN_WAITING_EXECUTE : ProcessType.MAIN_WAITING_EXECUTE);
				users.add(notifyuser);
			}
		} else {
			for (Copytor executor : operator.getCopytor()) {
				Record userinfo = getUsersListByUserName(executor.getProcessinguser());
				Map<String, String> notifyuser = new HashMap<>();
				notifyuser.put("phone_number", userinfo.getStr("mobile"));
				notifyuser.put("activity_type",
						isExecutor ? ProcessType.MAIN_WAITING_EXECUTE : ProcessType.MAIN_WAITING_EXECUTE);
				users.add(notifyuser);
			}
		}
		// 用于通知
		notifyBody.put("users", users);
		try {
			notifyDingTalkService.notify(mainID, JSON.toJSONString(notifyBody));
		} catch (Exception e) {
			// 通知失败时，返回的创建订单是成功，但是提示发送消息失败
			log.error(e.getMessage(), e);
			return e.getMessage();
		}
		return "执行成功";
	}

	// 执行人转发
	// 1、主表不做操作，写这只是不修改下面2，3，4的序号
	// 2、修改子表状态
	// 3、添加历史表
	// 4、删除任务表
	public Map<String, Object> executorRedeploy(Operator operator) {
		Map<String, Object> result = new HashMap<>();

		// 1、修改主表状态todo添加历史执行人
		Record movetasktable = Db.findById("movetasktable", operator.getId());
		// 3、添加历史表
		Record operatorInfo = getUsersListByUserName(operator.getProcessinguser());
		String executorListValue = "";
		for (Executor executor : operator.getExecutor()) {
			executorListValue = executorListValue + "," + executor.getProcessingusername();
		}
		String commment = "派发工单到" + StrUtil.removePrefix(executorListValue, ",") + ",处理";
		Record jbpm4OasProcessHistoryForClose = getJbpm4OasProcessHistoryForAudit(movetasktable, operatorInfo,
				StatusEnum.EXECUTEZF, commment);
		// 2、修改子表状态
		// 原子表信息
		Record movetasktableprocessInfo = Db.findById("movetasktableprocess ", operator.getSid());
		// 新加子表信息
		List<Record> movetasktableprocesNewList = getMovetasktableprocesByMovetasktableprocesList(
				movetasktableprocessInfo, operator, true);
		// 获取任务表
		Record tasknewInfo = Db.findFirst("select * from tasknew where TICKETID = ? and PROCESSINGUSERS=? ",
				movetasktableprocessInfo.getStr("ID"), operator.getProcessinguser());
		if (null == tasknewInfo) {
			result.put("info", "任务表无数据");
			result.put("success", false);
			return result;
		}
		// 事务处理,
		boolean succeed = false;
		try {
			succeed = Db.tx(new IAtom() {
				@Override
				public boolean run() throws SQLException {
					// 插入历史表
					if (!Db.save("JBPM4_OAS_PROCESS_HISTORY", jbpm4OasProcessHistoryForClose)) {
						return false;
					}
					// 修改子表状态
					Record movetasktableprocess = Db
							.findById("movetasktableprocess", movetasktableprocessInfo.get("ID"))
							.set("ACTIVITYNAME", "已转派");
					if (!Db.update("movetasktableprocess", movetasktableprocess)) {
						return false;
					}
					for (Record movetasktableprocesNew : movetasktableprocesNewList) {
						// 插入新的子表
						if (!Db.save("movetasktableprocess", movetasktableprocesNew)) {
							return false;
						}
						// 插入新的任务表
						if (!Db.save("tasknew",
								getTaskRecordByTaskRecord(movetasktableprocesNew.getStr("EXECUTORUSER"),
										movetasktableprocesNew.getStr("EXECUTORNAME"),
										movetasktableprocesNew.getLong("ID"), tasknewInfo, true))) {
							return false;
						}
					}
					// 4、删除任务表
					int deletetasknew = Db.delete("delete from tasknew where ID=? ", tasknewInfo.getLong("ID"));

					return deletetasknew == 1;
				}
			});

			result.put("info", this.notifyDing(operator.getId() + "", operator, true));
		} catch (Exception e) {
			log.info("执行--信息失败");
			succeed = false;
			result.put("info", e.getMessage());
		}

		result.put("success", succeed);
		return result;
	}

	// 抄送人转发
	// 1、主表不做操作，写这只是不修改下面2，3，4的序号
	// 2、修改子表状态
	// 3、添加历史表
	// 4、删除任务表
	public Map<String, Object> copytorRedeploy(Operator operator) {
		Map<String, Object> result = new HashMap<>();
		// 1、修改主表状态todo添加历史执行人
		Record movetasktable = Db.findById("movetasktable", operator.getId());

		// 3、添加历史表
		Record operatorInfo = getUsersListByUserName(operator.getProcessinguser());
		String executorListValue = "";
		for (Copytor copytor : operator.getCopytor()) {
			executorListValue = executorListValue + "," + copytor.getProcessingusername();
		}
		String commment = "派发工单到" + StrUtil.removePrefix(executorListValue, ",") + ",抄送";
		Record jbpm4OasProcessHistoryForClose = getJbpm4OasProcessHistoryForAudit(movetasktable, operatorInfo,
				StatusEnum.COPYZF, commment);/////////////////// --------
		// 2、修改子表状态
		// 原子表信息
		Record movetasktableprocessInfo = Db.findById("movetasktableprocess ", operator.getSid());
		// 新加子表信息
		List<Record> movetasktableprocesNewList = getMovetasktableprocesByMovetasktableprocesList(
				movetasktableprocessInfo, operator, false);
		// 获取任务表
		Record tasknewInfo = Db.findFirst("select * from tasknew where TICKETID = ? and PROCESSINGUSERS=? ",
				movetasktableprocessInfo.getStr("ID"), operator.getProcessinguser());
		if (null == tasknewInfo) {
			result.put("info", "任务表无数据");
			result.put("success", false);
			return result;
		}
		// 事务处理,
		boolean succeed = false;
		try {
			succeed = Db.tx(new IAtom() {
				@Override
				public boolean run() throws SQLException {
					// 插入历史表
					if (!Db.save("JBPM4_OAS_PROCESS_HISTORY", jbpm4OasProcessHistoryForClose)) {
						return false;
					}
					// 修改子表状态
					Record movetasktableprocess = Db
							.findById("movetasktableprocess", movetasktableprocessInfo.get("ID"))
							.set("ACTIVITYNAME", "已转派");
					Db.update("movetasktableprocess", movetasktableprocess);

					for (Record movetasktableprocesNew : movetasktableprocesNewList) {
						// 插入新的子表
						if (!Db.save("movetasktableprocess", movetasktableprocesNew)) {
							return false;
						}
						// 插入新的任务表
						if (!Db.save("tasknew",
								getTaskRecordByTaskRecord(movetasktableprocesNew.getStr("COPYTOUSER"),
										movetasktableprocesNew.getStr("COPYTONAME"), movetasktableprocesNew.get("ID"),
										tasknewInfo, true))) {
							return false;
						}
					}

					// 4、删除任务表
					int deletetasknew = Db.delete("delete from tasknew where ID=? ", tasknewInfo.getStr("ID"));

					return deletetasknew == 1;
				}
			});
			result.put("info", this.notifyDing(operator.getId() + "", operator, false));
		} catch (Exception e) {
			log.info("执行--信息失败");
			succeed = false;
			result.put("info", e.getMessage());
		}

		result.put("success", succeed);
		return result;
	}

	// 查询//太麻烦，简单的没会写，啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
	public Page<Movetasktable> list(Map<String, String> paras, int pageNumber, int pageSize) {

		String sql = " where 1=1 ";

		// or 条件
		if (paras.containsKey("content")) {
			String content = paras.get("content");
			sql += " and (";
			sql = sql + " ( theme like '%" + content + "%' )";
			sql = sql + " or ( activityname like '%" + content + "%' )";
			sql = sql + " or ( description like '%" + content + "%' )";
			sql += ")";
		}

		if (paras.containsKey("activityname")) {
			String activityname = paras.get("activityname");
			sql = sql + " and (activityname = '" + activityname + "')";
		}

		if (paras.containsKey("executor") || paras.containsKey("copytor") || paras.containsKey("proposeruser")) {
			sql = sql + " and ( 1=1 ";
			if (paras.containsKey("executor")) {
				String executor = paras.get("executor");
				sql = sql + " or (id in (select MAINTICKETID from movetasktableprocess where executoruser like '%"
						+ executor + "%'))";
			}

			if (paras.containsKey("copytor")) {
				String executor = paras.get("copytor");
				sql = sql + " or (id in (select MAINTICKETID from movetasktableprocess where copytouser like '%"
						+ executor + "%'))";
			}

			if (paras.containsKey("proposeruser")) {
				String proposeruser = paras.get("proposeruser");
				sql = sql + " or (proposeruser = '" + proposeruser + "')";
			}

			sql = sql + " )";
		}

		return movetasktable.paginate(pageNumber, pageSize, "select distinct *",
				" from MOVETASKTABLE " + sql + " order by createtime desc");

	}

	// 获取执行人信息
	private List<Record> getExecutorRecord(List<Executor> executors, long mainId) {

		List<Record> listExecutorRecord = new ArrayList<>();
		if (executors == null) {
			executors = new ArrayList<>();
		}
		for (Executor executor : executors) {
			Record movetasktableper = new Record().set("ID", getSqu()).set("STATION", executor.getStation())
					.set("REQUIREMENT", executor.getRequirement())// ？？？
					.set("MAINTICKETID", mainId).set("PROCESSINGUSER", executor.getProcessinguser())
					.set("PROCESSINGUSERNAME", executor.getProcessingusername()).set("CITY", executor.getStation())
					.set("TASKTYPE", executor.getTasktype())// 执行、抄送
					.set("STATIONID", executor.getStationid());
			listExecutorRecord.add(movetasktableper);
		}
		return listExecutorRecord;
	}

	// 获取抄送人信息
	private List<Record> getCopytorRecord(List<Copytor> copytors, long mainId) {

		List<Record> listCopytorRecord = new ArrayList<>();
		if (copytors == null) {
			copytors = new ArrayList<>();
		}
		for (Copytor copytor : copytors) {
			Record movetasktableper = new Record().set("ID", getSqu()).set("STATION", copytor.getStation())
					.set("REQUIREMENT", copytor.getRequirement())// ？？？
					.set("MAINTICKETID", mainId).set("PROCESSINGUSER", copytor.getProcessinguser())
					.set("PROCESSINGUSERNAME", copytor.getProcessingusername()).set("CITY", copytor.getCity())
					.set("TASKTYPE", copytor.getTasktype())// 执行、抄送
					.set("STATIONID", copytor.getStationid());
			listCopytorRecord.add(movetasktableper);
		}
		return listCopytorRecord;
	}

	private Long getSqu() {
		// 从数据库中获取，目录mysql没有，先写死
//        return System.currentTimeMillis()+squ.incrementAndGet();
//		Record first = Db.findFirst("select SEQ_GEN_SEQUENCE.NEXTVAL AS ID from dual");
//		long id = Long.parseLong(first.get("ID") + "");
		return Db.queryLong("select SEQ_GEN_SEQUENCE.NEXTVAL AS ID from dual");
	}

//	private static AtomicInteger squ = new AtomicInteger(1000);// todo从数据库里取最大

	private String getNo(String netType, String locationid) {
		// 网络类型+省分或地市+任务调度-+日期+序号 序号：拼之前先去数据库里查出当天工单号后三位最大的数加1

		String no = netType;
		no = no + ("2".equals(locationid) ? "省分" : "地市") + "任务调度-";
		Record maxId = Db
				.findFirst("SELECT  substr(MAX(no), -3, 3)  as ID FROM movetasktable where no like '%" + no + "%'");
		String qu = "-" + df.format(Integer.parseInt(maxId.get("ID")) + 1);
//        oracle
		no = no + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + qu;
//        mysql
//        no = no + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))+squ.incrementAndGet();
		return no;
	}

	public Map<String, Object> detail(Long id) {
		Map<String, Object> order = new HashMap<>();
		Record movetasktable = Db.findById("movetasktable", id);
		Map<String, Object> map = upToLower(movetasktable.toMap());
		List<Record> movetasktableprocessList = Db.find("select * from movetasktableprocess where MAINTICKETID=?", id);
		List<Record> movetasktableperList = Db.find("select * from movetasktableper where MAINTICKETID=?", id);
		map.put("movetasktableprocess", movetasktableprocessList.stream().map(m -> upToLower(m.toMap())).toList());
		map.put("movetasktableper", movetasktableperList.stream().map(m -> upToLower(m.toMap())).toList());
		return map;
	}

	public List<Jbpm4OasProcessHistory> history(long id) {

		List<Jbpm4OasProcessHistory> list = jbpm4OasProcessHistory
				.find("select * from JBPM4_OAS_PROCESS_HISTORY where ticketid = ?", id);
		return list;

	}

	private Map<String, Object> upToLower(Map<String, Object> source) {
		Map<String, Object> map = new HashMap<>();
		source.forEach((k, v) -> {
			map.put(k.toLowerCase(), v);
		});
		return map;
	}

}
